﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using NewsPublish.Model.Entity;
using NewsPublish.Model.Request;
using NewsPublish.Model.Response;

namespace JT.WEB.Service
{

    public class NewsService
    {
        private readonly ContextNews _db;
        public NewsService(ContextNews db)
        {
            this._db = db;
        }
        public ResponseModel AddNewsClassify(AddNewsClassify newsClassify)
        {
            bool exit = _db.NewsClassify.FirstOrDefault(c => c.Name == newsClassify.Name) != null;
            if (exit)
            {
                return new ResponseModel { code = 0, result = "该类别已存在" };
            }
            NewsClassify classify = new NewsClassify
            {
                Name = newsClassify.Name,
                Sort = newsClassify.Sort,
                Remark = newsClassify.Remark
            };
            _db.NewsClassify.Add(classify);
            int i = _db.SaveChanges();
            if (i > 0)
            {
                return new ResponseModel { code = 200, result = "新闻类别添加成功" };
            }
            return new ResponseModel { code = 0, result = "新闻类别添加失败" };
        }
        public ResponseModel GetOneNewsClassify(int Id)
        {
            NewsClassify classify = _db.NewsClassify.Find(Id);
            if (classify == null)
            {
                return new ResponseModel { code = 0, result = "该类别不存在" };
            }
            return new ResponseModel
            {
                code = 200,
                result = "新闻类别获取成功",
                data = new NewsClassifyModel
                {
                    Id = classify.Id,
                    Name = classify.Name,
                    Sort = classify.Sort,
                    Remark = classify.Remark
                }
            };
        }

        //获取下个新闻类别
        private NewsClassify GetOneNewsClassify(Expression<Func<NewsClassify, bool>> where)
        {
            return _db.NewsClassify.FirstOrDefault(where);
        }
        //编辑一个新闻类别
        public ResponseModel EditNewsClassify(EditNewsClassify editNewsClassify)
        {
            NewsClassify classify = this.GetOneNewsClassify(c => c.Id == editNewsClassify.Id);
            if (classify == null)
            {
                return new ResponseModel { code = 0, result = "该类别不存在" };
            }

            classify.Name = editNewsClassify.Name;
            classify.Sort = editNewsClassify.Sort;
            classify.Remark = editNewsClassify.Remark;

            _db.NewsClassify.Update(classify);
            int i = _db.SaveChanges();
            if (i > 0)
            {
                return new ResponseModel { code = 200, result = "新闻类别添加成功" };
            }
            return new ResponseModel { code = 0, result = "新闻类别添加失败" };
        }

        //获取新闻列表
        public ResponseModel GetNewsClassifyList()
        {
           List<NewsClassify> classifyList = _db.NewsClassify.OrderByDescending(c => c.Sort).ToList();
            ResponseModel response = new ResponseModel { code = 200, result = "新闻列表获取成功" };
            response.data = new List<NewsClassifyModel>();
            foreach (NewsClassify item in classifyList)
            {
                response.data.Add(new NewsClassifyModel
                {
                    Id = item.Id,
                    Sort = item.Sort,
                    Name = item.Name,
                    Remark = item.Remark
                });
            }
            return response;
        }
        //添加新闻 
        public ResponseModel AddNews(AddNews addNews)
        {
            if (addNews is null)
            {
                throw new ArgumentNullException(nameof(addNews));
            }

            NewsClassify classify = this.GetOneNewsClassify(c => c.Id == addNews.NewsClassifyId);
            if (classify == null)
            {
                return new ResponseModel { code = 0, result = "新闻类别不存在" };
            }
            News n = new News
            {
                NewsClassifyId = addNews.NewsClassifyId,
                Title = addNews.Title,
                Image = addNews.Image,
                Contents = addNews.Contents,
                ContentsHtml = addNews.ContentsHtml,
                Remark = addNews.Remark,
                PublishDate = DateTime.Now
            };
            _db.News.Add(n);
            int i = _db.SaveChanges();
            if (i > 0)
            {
                return new ResponseModel { code = 200, result = "添加新闻成功" };
            }
            return new ResponseModel { code = 0, result = "添加新闻失败" };

        }
        //获取新闻
        public ResponseModel GetOneNews(int id)
        {
            News news = _db.News.Include("NewsClassify").Include("NewsComments").FirstOrDefault(c => c.Id == id);
            if (news == null)
            {
                return new ResponseModel { code = 0, result = "新闻不存在" };
            }
            return new ResponseModel
            {
                code = 200,
                result = "新闻获取成功",
                data = new NewsModel
                {
                    Id = news.Id,
                    ClassifyName = news.NewsClassify.Name,
                    Title = news.Title,
                    Image = news.Image,
                    Contents = news.Contents,
                    ContentsHtml = news.ContentsHtml,
                    PublishDate = news.PublishDate.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture),
                    Remark = news.Remark,
                    CommentCount = news.NewsComments.Count()
                }
            };
        }

        //删除一个新闻
        public ResponseModel DelOneNews(int id)
        {
            News news = _db.News.Include("NewsClassify").Include("NewsComments").FirstOrDefault(c => c.Id == id);
            if (news == null)
            {
                return new ResponseModel { code = 0, result = "新闻不存在" };
            }

            _db.News.Remove(news);
            int i = _db.SaveChanges();
            if (i > 0)
            {
                return new ResponseModel { code = 200, result = "删除新闻成功" };
            }
            return new ResponseModel { code = 0, result = "删除新闻失败" };

        }
        public ResponseModel NewsPageQuery(int pageSize, int pageIndex, out int total, List<Expression<Func<News, bool>>> where)
        {
            IQueryable<News> list = _db.News.Include("NewsClassify").Include("NewsComments");
            foreach (Expression<Func<News, bool>> item in where)
            {
                list = list.Where(item);
            }
            total = list.Count();
            List<News> pageData = list.OrderByDescending(c => c.PublishDate).Skip(pageSize * (pageIndex - 1)).Take(pageSize).ToList();
            ResponseModel response = new ResponseModel { code = 200, result = "分布新闻获取成功" };
            response.data = new List<NewsModel>();
            foreach (News news in pageData)
            {
                response.data.Add(new NewsModel
                {
                    Id = news.Id,
                    ClassifyName = news.NewsClassify.Name,
                    Title = news.Title,
                    Image = news.Image,
                    Contents = news.Contents.Length > 50 ? news.Contents.Substring(0, 20) + "..." : news.Contents,
                    PublishDate = news.PublishDate.ToString("yyyy-MM-dd"),
                    Remark = news.Remark,
                    CommentCount = news.NewsComments.Count()
                });
            }
            return response;

        }
        //查询新闻列表
        public ResponseModel GetNewsList(Expression<Func<News, bool>> where, int topCount)
        {
            IQueryable<News> list = _db.News.Include(t => t.NewsClassify).Include(t => t.NewsComments).Where(where).Take(topCount);

            ResponseModel response = new ResponseModel();
            if (!list.Any())
            {
                response.code = 0;
                response.result = "新闻不存在";
                return response;
            }
            response.code = 200;
            response.result = "新闻获取成功";
            response.data = new List<NewsModel>();
            foreach (News news in list)
            {
                response.data.Add(new NewsModel
                {
                    Id = news.Id,
                    ClassifyName = news.NewsClassify.Name,
                    Title = news.Title,
                    Image = news.Image,
                    Contents = (news.Contents.Length > 80 ? news.Contents.Substring(0, 80) : news.Contents) + "...",
                    PublishDate = news.PublishDate.ToString("yyyy-MM-dd"),
                    Remark = DateTime.Now.Date.CompareTo(news.PublishDate) <= 0 ? "NEW" : news.Remark,
                    CommentCount = news.NewsComments.Count(),
                    Badge = news.PublishDate.CompareTo(DateTime.Now.Date) >= 0 ? "最新" : "",
                    Hot = (news.PublishDate.CompareTo(DateTime.Now.Date.AddDays(-7)) >= 0 && news.NewsComments.Count != 0) ? "热点" : ""
                });


            }

            return response;

        }

        public ResponseModel GetNewCommentNewsList(Expression<Func<News, bool>> where, int topCount)
        {
            IQueryable<int> newsIds = _db.NewsComment.OrderByDescending(c => c.AddTime).GroupBy(c => c.NewsId).Select(c => c.Key).Take(topCount);
            IOrderedQueryable<News> list = _db.News.Include("NewsClassify").Include("NewsComment").Where(c => newsIds.Contains(c.Id)).OrderByDescending(c => c.PublishDate);
            ResponseModel response = new ResponseModel { code = 200, result = "最新评论新闻列表获取成功" };
            response.data = new List<NewsModel>();
            foreach (News news in list)
            {
                response.data.Add(new NewsModel
                {
                    Id = news.Id,
                    ClassifyName = news.NewsClassify.Name,
                    Title = news.Title,
                    Image = news.Image,
                    Contents = news.Contents.Length > 50 ? news.Contents.Substring(0, 50) : news.Contents,
                    PublishDate = news.PublishDate.ToString("yyyy-MM-dd"),
                    Remark = news.Remark,
                    CommentCount = news.NewsComments.Count()
                });
            }
            return response;

        }
    }

}
